package com.fdb.efp.nls.service.impl.sed.repay;

import com.fdb.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.fdb.basic.framework.core.constant.BaseConstant;
import com.fdb.basic.framework.core.constant.SDicToLocalConstant;
import com.fdb.basic.framework.core.exception.ExternalSysException;
import com.fdb.basic.framework.core.exception.OcmSystemException;
import com.fdb.basic.framework.core.util.DateUtility;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.basic.framework.core.util.TimeUtil;
import com.fdb.basic.framework.core.util.sdic.SDicToLocal;
import com.fdb.efp.nls.common.ConsoleConstant;
import com.fdb.efp.nls.service.facade.PubSysInfoService;
import com.fdb.efp.esb.service.bo.req.hj.ReqLoanBalanceBean;
import com.fdb.efp.esb.service.bo.req.hj.ReqLoanInfoQueryBean;
import com.fdb.efp.esb.service.bo.req.hj.ReqRepaymentDetailsInfoQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.AcctDtlInfBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespLoanBalanceQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespLoanInfoQueryBean;
import com.fdb.efp.esb.service.bo.resp.hj.RespRepaymentPlanListQueryBean;
import com.fdb.efp.esb.service.facade.hj.LoanInfoQueryService;
import com.fdb.efp.nls.common.LoanConstant;
import com.fdb.efp.nls.service.facade.AccLoanService;
import com.fdb.efp.nls.service.facade.LoanRepayPlanService;
import com.fdb.efp.nls.service.vo.AccLoanVO;
import com.fdb.efp.loan.service.vo.LoanRepayDetailVO;
import com.fdb.efp.loan.service.vo.LoanRepayPlanVO;
import com.fdb.efp.nls.common.constant.sed.SedNlsEnum;
import com.fdb.efp.nls.common.constant.sed.SedNlsEnum.ExceptionLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 需求编号：【2019D0519】（业务提的需求编号）
 * 问题编号：【xxxxxxx】（若不是因为修复问题而新增该类，则留空）
 * 开发人员：qiuyf
 * 创建日期：2019年5月31日 下午7:26:34
 * 功能描述：借据信息、还款计划信息更新插槽服务
 */
@Service("synInfoAfterRepayService")
public class SynInfoAfterRepayServiceImpl extends RepaySoltServiceImpl{

	private static final Logger logger = LoggerFactory.getLogger(SynInfoAfterRepayServiceImpl.class);

	//储存系统营业日期
	private static final Map<String, String> openDayMap = new HashMap<>();
	// 根据“还款期数”，保存对应的“是否逾期过”【1是 0否】，<期数,是否逾期过>
	private static final Map<String, String> termIsOverDueMap = new HashMap<String, String>();

	@Override
	protected void doExecute(NlsProcessBizVO nlsProcessBizVo, LoanRepayDetailVO loanRepayDetailVO) throws Exception {
		String setlSeq = loanRepayDetailVO.getSetlSeq();
		String loanNo = loanRepayDetailVO.getLoanNo();
		RespLoanInfoQueryBean respLoanInfo = null;
		RespRepaymentPlanListQueryBean respRepayPlan = null;
		RespLoanBalanceQueryBean respLoanBalanceQueryBean = null;
		String exceptionLocation = loanRepayDetailVO.getExceptionLocation();
		logger.info("======>借据信息、还款计划信息更新插槽服务开始,流水号为:"+setlSeq+"<======");
		try {
			if(StringUtil.isNotEmpty(exceptionLocation)) {
				logger.info("======>借据信息、还款计划信息更新插槽服务重跑开始,异常标识为:"+exceptionLocation+"<======");
			}
			// 通过借据号查询借据信息，获取贷款号、发放号
			AccLoanVO accLoanVO = new AccLoanVO();
			accLoanVO.setBillNo(loanNo);
			accLoanVO =	accLoanService.queryByPk(accLoanVO);
			if(Objects.isNull(accLoanVO)) {
				throw new OcmSystemException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(), "还款成功后，通过借据号【" + loanNo + "】，获取到的借据信息为空！");
			}
			String loanSeq = accLoanVO.getLoanSeq();
			String distrNo = accLoanVO.getDistrNo();

			ReqLoanInfoQueryBean reqLoanInfoQueryBean = new ReqLoanInfoQueryBean();
			ReqRepaymentDetailsInfoQueryBean reqRepaymentDetailsInfoQueryBean = new ReqRepaymentDetailsInfoQueryBean();
			ReqLoanBalanceBean reqLoanBalanceBean = new ReqLoanBalanceBean();
			try {
				logger.info("前往互金查询借据信息开始---------------------");
				reqLoanInfoQueryBean.setLoanNo(loanSeq);
				reqLoanInfoQueryBean.setDistrNo(distrNo);
				//respLoanInfo = loanInfoQueryService.loanInfoQuery(reqLoanInfoQueryBean);
				logger.info("前往互金查询借据信息结束---------------------");

				logger.info("前往互金查询还款计划明细开始---------------------");
				reqRepaymentDetailsInfoQueryBean.setAcctNo(loanSeq);
				reqRepaymentDetailsInfoQueryBean.setDistrNo(distrNo);
				//respRepayPlan = loanInfoQueryService.repaymentPlanListQuery(reqRepaymentDetailsInfoQueryBean);
				logger.info("前往互金查询还款计划明细结束---------------------");

				logger.info("前往互金查询贷款余额开始---------------------");
				reqLoanBalanceBean.setLoanNo(loanSeq);
				reqLoanBalanceBean.setDistrNo(distrNo);
				//respLoanBalanceQueryBean = loanInfoQueryService.loanBalanceQuery(reqLoanBalanceBean);
				logger.info("前往互金查询贷款余额结束---------------------");
			} catch (Exception e) {
				throw new ExternalSysException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(), "还款成功后，同步借据、还款计划，调用互金接口异常，异常信息为："+e.getMessage());
			}
			if(StringUtil.isNullorBank(exceptionLocation) || SedNlsEnum.ExceptionLocation.INSERT_LOAN_PLAN_AFTER_REPAY.getValue().equals(exceptionLocation)) {
				// 还款计划更新（先全删，后全插）
				this.synLoanRepayPlan(respRepayPlan, accLoanVO);
			}
			// 借据信息更新
			this.synAccLoan(accLoanVO, respLoanInfo, respLoanBalanceQueryBean);
		} catch (Exception e) {
			logger.error("--------执行借据信息、还款计划信息更新插槽服务失败，异常信息为：" + e.getMessage());
			logger.error(Arrays.toString(e.getStackTrace()));
			nlsProcessBizVo.setExceptionFlag(true);
			nlsProcessBizVo.setExceptionMsg(e);
		} finally {
			logger.info("======>借据信息、还款计划信息更新插槽服务结束,流水号为:"+setlSeq+"<======");
		}
	}

	// 还款计划实时同步
	private void synLoanRepayPlan(RespRepaymentPlanListQueryBean respRepayPlan, AccLoanVO accLoanVO) throws OcmSystemException {
		String loanNo = accLoanVO.getBillNo();
		logger.info("======>借据信息、还款计划信息更新插槽服务结束,同步还款计划信息开始,借据号为:"+loanNo+"<======");
		try {
			// 通过借据编号查询还款计划信息
			List<LoanRepayPlanVO> localLRPVoLists = loanRepayPlanService.qryAllByLoanNo(loanNo);

			if(null == localLRPVoLists || localLRPVoLists.isEmpty()) {
				throw new OcmSystemException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(), "通过借据号【" + loanNo + "】，获取到的还款计划信息为空！");
			}

			// 根据“还款期数”，保存对应的“结清日期”
			Map<String, String> termClearDateMap = new HashMap<String, String>();
			Iterator<LoanRepayPlanVO> iterator = localLRPVoLists.iterator();
			while(iterator.hasNext()) {
				LoanRepayPlanVO lRepPlanVO = iterator.next();
				//根据“还款期数”，保存对应的“是否逾期过”
				termIsOverDueMap.put(lRepPlanVO.getTerm().toString(), lRepPlanVO.getIsOverDue());
				termClearDateMap.put(lRepPlanVO.getTerm().toString(), lRepPlanVO.getClearDate());
			}

			// 根据借据编号删除本地原还款计划信息
			int deleteNum = loanRepayPlanService.deleteByLoanNo(loanNo);
			if(deleteNum < 0) {
				throw new OcmSystemException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(),  "根据借据号【" + loanNo + "】，删除还款计划信息失败！");
			}
			List<LoanRepayPlanVO> insertLists = new ArrayList<LoanRepayPlanVO>(respRepayPlan.getAcctDtlInfArry().size());
			for (int i = 0; i < respRepayPlan.getAcctDtlInfArry().size(); i++) {
				AcctDtlInfBean acctDtlInfBean = respRepayPlan.getAcctDtlInfArry().get(i);
				LoanRepayPlanVO loanRepayPlan = new LoanRepayPlanVO();

				/************************************************ 借据信息同步来源于【调用互金接口返回的】 ****** start */ 
				// 借据编号  = 账户主键
				loanRepayPlan.setRefNbr(acctDtlInfBean.getAcctKwd());
				// 还款期数  = 期次
				loanRepayPlan.setTerm(Integer.parseInt(acctDtlInfBean.getRpyTime()));
				// 开始日期   = 起始日期
				loanRepayPlan.setBeginDate(DateUtility.format8To10(acctDtlInfBean.getStartDt()));
				// 到期日期  = 终止日期
				loanRepayPlan.setStmtDate(DateUtility.format8To10(acctDtlInfBean.getEndDt()));
				// 期数状态
				loanRepayPlan.setStatus(this.getTermStatus(acctDtlInfBean));
				//计划本金
				double principal = acctDtlInfBean.getPlanPrin();
				//计划利息
				double interest = acctDtlInfBean.getPlanInt();
				//出单罚息
				double penaltyDue = acctDtlInfBean.getIssuePnyInt();
				//出单复利
				double comIntDue = acctDtlInfBean.getIssueCmpdInt();

				// 应还本金  = 计划本金
				loanRepayPlan.setPrincipal(new BigDecimal(principal));
				// 已还本金  = 实还本金
				loanRepayPlan.setPrincipalPaid(new BigDecimal(acctDtlInfBean.getActRpyPrin()));
				// 应还利息 = 计划利息
				loanRepayPlan.setInterest(new BigDecimal(interest));
				// 已还利息 = 实还利息
				loanRepayPlan.setInterestPaid(new BigDecimal(acctDtlInfBean.getActRpyInt()));
				// 应还罚息 = 出单罚息
				loanRepayPlan.setPenaltyDue(new BigDecimal(penaltyDue));
				// 已还罚息 = 实还罚息
				loanRepayPlan.setPenaltyPaid(new BigDecimal(acctDtlInfBean.getActRpyPnyInt()));
				// 应还复利 = 出单复利
				loanRepayPlan.setComIntDue(new BigDecimal(comIntDue));
				// 已还复利  = 实还复利
				loanRepayPlan.setComIntPaid(new BigDecimal(acctDtlInfBean.getActRpyCmpdInt()));
				// 应还费用
				loanRepayPlan.setFeeDue(BigDecimal.ZERO);
				// 已还费用
				loanRepayPlan.setFeePaid(BigDecimal.ZERO);
				//期供 = 应还本金+应还利息+应还罚息+应还复利 
				loanRepayPlan.setPerAmt(new BigDecimal(principal + interest + penaltyDue + comIntDue));
				/************************************************ 借据信息同步来源于【调用互金接口返回的】 ****** end   */ 

				/** ---------------- 其他字段赋值 ------------ start --------- */
				// 产品ID
				loanRepayPlan.setProductCd(accLoanVO.getPrdId());
				/**
				 *  是否逾期  1：是 ，0：否   
				 *  【变更】 赋值本地表对应期数的“是否逾期过”字段值
				 *  @date 2019/07/01
				 */
				loanRepayPlan.setIsOverDue(this.getIsOverDueMethod(acctDtlInfBean.getRpyTime(), loanRepayPlan.getStatus()));
				// 还款计划size
				loanRepayPlan.setInitTerm(respRepayPlan.getAcctDtlInfArry().size());
				// 结清日期 
				loanRepayPlan.setClearDate(this.getClearDate(acctDtlInfBean, termClearDateMap));
				/** ---------------- 其他字段赋值 ------------ end   --------- */

				insertLists.add(loanRepayPlan);
			}
			int num = loanRepayPlanService.batchInsert(insertLists);
			if (num < 0){
				throw new OcmSystemException(ExceptionLocation.INSERT_LOAN_PLAN_AFTER_REPAY.getValue(),  "更新还款计划失败，借据号【" + loanNo + "】");
			}
		} catch (Exception e) {
			throw new OcmSystemException(e);
		} finally {
			logger.info("======>借据信息、还款计划信息更新插槽服务结束,同步还款计划信息结束,借据号为:"+loanNo+"<======");
		}
	}

	/**
	 * 判断“已到期” 
		N 正常
		O 逾期
		P 结清
		到期日期<营业日期，应还=实还或未还为0，状态为P,应还!=实还或未还不为0，状态为O;
		到期日期=营业日期，应还=实还或未还为0，状态为P,应还!=实还或未还不为0，状态为N;
		到期日期>营业日期，状态为N
	 */
	private String getTermStatus(AcctDtlInfBean acctDtlInfBean) {
		String termStatus = null;
		//到期日期  = 终止日期
		String endDate = acctDtlInfBean.getEndDt();
		String sysDate = this.getSysOpenDay();
		//应还本金 = 计划本金
		double principal = acctDtlInfBean.getPlanPrin();
		//实还本金
		double principalPaid =  acctDtlInfBean.getActRpyPrin();
		try {
			// 到期日期<营业日期，应还=实还或未还为0，状态为P,应还!=实还或未还不为0，状态为O
			if(TimeUtil.compareDates(endDate, sysDate) == -1) {
				if(principal == principalPaid) {
					termStatus = LoanConstant.REPAYPLAN_STATUE_P;
				}else {
					termStatus = LoanConstant.REPAYPLAN_STATUE_O;
				}
			}
			// 到期日期=营业日期，应还=实还或未还为0，状态为P,应还!=实还或未还不为0，状态为N
			else if(TimeUtil.compareDates(endDate, sysDate) == 0) {
				if(principal == principalPaid) {
					termStatus = LoanConstant.REPAYPLAN_STATUE_P;
				}else {
					termStatus = LoanConstant.REPAYPLAN_STATUE_N;
				}
			}
			// 到期日期>营业日期，状态为N
			else if(TimeUtil.compareDates(endDate, sysDate) == 1) {
				termStatus = LoanConstant.REPAYPLAN_STATUE_N;
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("还款成功后，同步还款计划时，获取期数状态出现异常，异常信息为：", e);
		}
		return termStatus;
	}

	/**
	 * 获取结清日期
	 * 	1.当原结清日期不为空时，还是赋原结清日期；
	 *  2.当原结清日期为空时，若计划本金 = 实还本金，计划利息 = 实还利息， 出单罚息 = 实还罚息， 出单复利 = 实还复利，结清日期取系统营业日期，否则为null
	 */
	private String getClearDate(AcctDtlInfBean acctDtlInfBean, Map<String, String> termClearDateMap) {
		String clearDate = null;
		if(StringUtil.isStrNotEmpty(termClearDateMap.get(acctDtlInfBean.getRpyTime()))) {
			clearDate = termClearDateMap.get(acctDtlInfBean.getRpyTime());
		}else {
			if(acctDtlInfBean.getPlanPrin()==acctDtlInfBean.getActRpyPrin() && acctDtlInfBean.getPlanInt()==acctDtlInfBean.getActRpyInt() &&
					acctDtlInfBean.getIssuePnyInt()==acctDtlInfBean.getActRpyPnyInt() && acctDtlInfBean.getIssueCmpdInt()==acctDtlInfBean.getActRpyCmpdInt()) {
				clearDate = this.getSysOpenDay();
			}
		}
		return clearDate;
	}

	/**
	 * 获取“是否逾期过”字段值
	 */
	private String getIsOverDueMethod(String term, String termStatus) {
		String isOverDue = SedNlsEnum.YesOrNo.NO.getValue();
		//当原“是否逾期过”字段为“是”
		if(SedNlsEnum.YesOrNo.YES.getValue().equals(termIsOverDueMap.get(term))) {
			isOverDue = termIsOverDueMap.get(term);
		}
		//当原“是否逾期过”字段为“否”，且当前期数状态为“逾期”
		if(SedNlsEnum.YesOrNo.NO.getValue().equals(termIsOverDueMap.get(term)) && LoanConstant.REPAYPLAN_STATUE_O.equals(termStatus)) {
			isOverDue = SedNlsEnum.YesOrNo.YES.getValue();
			//更新期数为term的是否逾期过字段值
			termIsOverDueMap.put(term, isOverDue);
		}
		return isOverDue;
	}



	// 借据信息实时同步
	private void synAccLoan(AccLoanVO accLoanVO, RespLoanInfoQueryBean respLoanInfoQueryBean, RespLoanBalanceQueryBean respLoanBalanceQueryBean) throws OcmSystemException {
		String loanNo = accLoanVO.getBillNo();
		logger.info("======>借据信息、还款计划信息更新插槽服务结束,同步借据信息开始,借据号为:"+loanNo+"<======");
		try {
			/************************************************ 借据信息同步来源于【调用互金接口返回的】   ********************************* start */ 
			// 借据余额  = 贷款余额
			accLoanVO.setLoanBalance(respLoanBalanceQueryBean.getLoanBal());
			// 应收利息累计 = 出单利息
			accLoanVO.setReceIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getIssueInt());
			// 实收利息累计 = 已还利息
			accLoanVO.setActualIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydInt());
			// 欠息累计 = 应还利息
			accLoanVO.setDelayIntCumu(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblInt_1());
			// 应收复利累计  = 出单复利
			accLoanVO.setUnpdArrPrnBal(respLoanBalanceQueryBean.getLoanBal());
			// 实收拖欠本金的罚息    = 已还罚息
			accLoanVO.setActArrsIntBal(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydPnyInt());
			// 实收复利 = 已还复利
			accLoanVO.setActArrPrnBal(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydCmpdInt());
			// 拖欠本金的罚息（应收未收）  = 应还罚息
			accLoanVO.setUnpdArrsIntBal1(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblPnyInt_1());
			// 应收复利（应收未收） = 应还复利
			accLoanVO.setUnpdArrPrnBal1(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpyblCmpdInt_1());
			// 欠息累计 = 出单罚息
			accLoanVO.setDelayIntCumu1(respLoanBalanceQueryBean.getDstrInfArry()[0].getIssuePnyInt());

			String rulingIr = respLoanInfoQueryBean.getBnchmrkRate();
			// 基准利率
			accLoanVO.setRulingIr(StringUtil.isNotEmpty(rulingIr) ? new BigDecimal(rulingIr).divide(new BigDecimal("100")) : BigDecimal.ZERO);
			// 利息执行年利率  = 正常利率
			accLoanVO.setRealityIrY(null==respLoanInfoQueryBean.getComIntRate() ? BigDecimal.ZERO : respLoanInfoQueryBean.getComIntRate().divide(new BigDecimal("100")));
			// 结清日期 = 结清日期
			accLoanVO.setSettlDate(DateUtility.format8To10(respLoanInfoQueryBean.getCldDt()));
			String accSts = "";
			try {
				accSts = SDicToLocal.getLocalSysDicVal(SDicToLocalConstant.ACC_STATUS, respLoanInfoQueryBean.getAcctLdgrSt());
			} catch (Exception e) {
				e.printStackTrace();
				throw new OcmSystemException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(),  "更新借据表信息时,台账状态转换出错,借据号【" + accLoanVO.getBillNo() +"】");
			}
			// 台账状态  = 账户核算状态
			accLoanVO.setAccountStatus(accSts);
			if(ConsoleConstant.ACC_STATUS_1.equals(accSts)) {
				// 正常贷款余额  = 贷款余额 
				accLoanVO.setNormalBalance(respLoanBalanceQueryBean.getLoanBal());
				// 拖欠本金 = 0.00
				accLoanVO.setUnpdPrinBal(BigDecimal.ZERO);
			} else if(ConsoleConstant.ACC_STATUS_10.equals(accSts) || ConsoleConstant.ACC_STATUS_12.equals(accSts)) {
				// 拖欠本金 = 贷款余额
				accLoanVO.setUnpdPrinBal(respLoanBalanceQueryBean.getLoanBal());
				// 正常贷款余额 = 0.00
				accLoanVO.setNormalBalance(BigDecimal.ZERO);
			}
			// 宽限期
			accLoanVO.setGraceDay(StringUtil.isStrNotEmpty(respLoanInfoQueryBean.getGrcDay()) ? new BigDecimal(respLoanInfoQueryBean.getGrcDay()) : BigDecimal.ZERO);
			/************************************************ 借据信息同步来源于【调用互金接口返回的】   ********************************* end   */ 

			/******************* 借据信息同步来源于【还款计划表】************ start */  
			//根据借据号获取还款计划信息
			List<LoanRepayPlanVO> loanRepayPlanVOs = loanRepayPlanService.qryAllByLoanNo(loanNo);
			if(null==loanRepayPlanVOs || loanRepayPlanVOs.isEmpty()) {
				throw new OcmSystemException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(), "通过借据号【" + accLoanVO.getBillNo() +"】，查询到的还款计划信息为空！");
			}
			// 逾期起始日  期数最小的逾期到期日
			accLoanVO.setCapOverdueDate(this.getMinOverdueDate(loanRepayPlanVOs));
			// 当前逾期期数  还款计划中所有的期数状态为“逾期”的总数
			accLoanVO.setOverTimesCurrent(this.getOverTimesCurrent(loanRepayPlanVOs));
			// 累计逾期期数  统计“是否逾期过” 1：是 ，0：否   
			accLoanVO.setOverTimesTotal(this.getOverTimesTotal(loanRepayPlanVOs));
			// 最高逾期期数  统计连续期数状态为“逾期”的最多的一次
			accLoanVO.setMaxTimesTotal(this.getMaxTimesTotal(loanRepayPlanVOs));
			// 当前期数 【起始日 < 系统日期 <= 到日期】 
			accLoanVO.setCurrTerm(this.getCurTerm(loanRepayPlanVOs));
			/******************* 借据信息同步来源于【还款计划表】************ end   */

			// 最后修改时间
			accLoanVO.setLastUpdateTime(TimeUtil.getCurrentDateTime());
			// 最后修改人
			accLoanVO.setLastUpdateUser(BaseConstant.ADMIN);

			int num = accLoanService.updateByPk(accLoanVO);
			if (num < 0){
				throw new OcmSystemException(ExceptionLocation.SYN_INFO_AFTER_REPAY.getValue(),  "更新借据表信息出错------------借据号【" + accLoanVO.getBillNo() +"】");
			}
		} catch (Exception e) {
			throw new OcmSystemException(e);
		} finally {
			logger.info("======>借据信息、还款计划信息更新插槽服务结束,同步借据信息结束,借据号为:"+loanNo+"<======");
		}
	}

	/**
	 * 获取台账状态
	 * @author  qiuyf
	 * @since 2019年7月3日 下午9:10:18
	 * @version 0.1 初始为0.1,后续变更则修改
	 */
	@SuppressWarnings("unused")
	private String getAccLoanSts(String acctSts, String setledDate, BigDecimal loanBalance) {
		String accLoanSts = ConsoleConstant.ACC_STATUS_1;
		try {
			if(StringUtil.isStrNotEmpty(setledDate)) {
				String openDay = this.getSysOpenDay();
				// 营业日期大于等于结清日期
				if(TimeUtil.compareDates(openDay, setledDate) > -1) {
					accLoanSts = ConsoleConstant.ACC_STATUS_4;
				}
			}
			// 贷款余额小于等于0
			if(loanBalance.compareTo(BigDecimal.ZERO) < 1) {
				accLoanSts = ConsoleConstant.ACC_STATUS_4;
			}
			if(!ConsoleConstant.ACC_STATUS_4.equals(accLoanSts)) {
				accLoanSts = SDicToLocal.getLocalSysDicVal(SDicToLocalConstant.ACC_STATUS, acctSts);
			}
		} catch (Exception e) {
			logger.error("还款成功更新借据信息时，获取台账状态出现异常，异常信息为：", e);
		}
		return accLoanSts;
	}

	/**
	 * 逾期起始日（期数最小的逾期到期日）
	 */
	private String getMinOverdueDate(List<LoanRepayPlanVO> loanRepayPlanVOs) {
		List<LoanRepayPlanVO> resultList = loanRepayPlanVOs.stream()
				//筛选期数状态为“逾期”的还款计划信息
				.filter(lrpvo -> { return LoanConstant.REPAYPLAN_STATUE_O.equals(lrpvo.getStatus());})
				//根据期数升序排序信息
				.sorted(Comparator.comparing(LoanRepayPlanVO::getTerm)).collect(Collectors.toList());

		if(null==resultList || resultList.isEmpty()) {
			return null;
		}
		return resultList.get(0).getStmtDate();
	}

	/**
	 * 当前逾期期数 （还款计划中所有的期数状态为“逾期”的总数）
	 */
	private BigDecimal getOverTimesCurrent(List<LoanRepayPlanVO> loanRepayPlanVOs) {
		long result = loanRepayPlanVOs.stream()
				//筛选期数状态为“逾期”的还款计划信息
				.filter(lrpvo -> { return LoanConstant.REPAYPLAN_STATUE_O.equals(lrpvo.getStatus());})
				.count();
		return new BigDecimal(result);
	}


	/**
	 * 累计逾期期数
	 */
	private BigDecimal getOverTimesTotal(List<LoanRepayPlanVO> loanRepayPlanVOs) {
		long overTimeTotal = loanRepayPlanVOs.stream()
				.map(LoanRepayPlanVO::getIsOverDue)
				.filter(val -> { return SedNlsEnum.YesOrNo.YES.getValue().equals(val);}).
				count();
		return new BigDecimal(overTimeTotal);
	}

	/**
	 * 最高逾期期数 （统计连续期数状态为“逾期”的最多的一次）
	 */
	private BigDecimal getMaxTimesTotal(List<LoanRepayPlanVO> loanRepayPlanVOs) {
		int max = 1;
		int count = 1;
		for (int i = 0; i < loanRepayPlanVOs.size(); i++) {
			if ((loanRepayPlanVOs.get(i).getTerm() + 1) == loanRepayPlanVOs.get(i+1).getTerm()){
				count++;
				max = max > count ? max:count;
			}else {
				count = 1;
			}
		}
		return new BigDecimal(max);
	}

	/**
	 * 获取当前期数（起始日 < 系统营业日期 <= 到日期）
	 */
	private BigDecimal getCurTerm(List<LoanRepayPlanVO> loanRepayPlanVOs) {
		String openDay = this.getSysOpenDay();
		List<Integer> termList = loanRepayPlanVOs.stream()
				//过滤，条件：起始日 < 系统营业日期 <= 到日期
				.filter(lrp -> { return (TimeUtil.compareDate(lrp.getBeginDate(), openDay) == -1 && TimeUtil.compareDate(lrp.getStmtDate(), openDay) != -1);})
				//取期数
				.map(LoanRepayPlanVO::getTerm)
				//升序排序
				.sorted()
				//收集成list
				.collect(Collectors.toList());
		if(null==termList || termList.isEmpty()) {
			return BigDecimal.ZERO;
		}
		return new BigDecimal(termList.get(0));
	}


	/**
	 * 获取系统营业日期
	 */
	private String getSysOpenDay() {
		if(openDayMap.containsKey(BaseConstant.SYS_ID_1001)) {
			return openDayMap.get(BaseConstant.SYS_ID_1001);
		}
		String openDayStr = pubSysInfoService.getOpenday(BaseConstant.SYS_ID_1001);
		//将查询到的营业日期保存
		openDayMap.put(BaseConstant.SYS_ID_1001, openDayStr);
		return openDayStr;
	}

	@Autowired
	@Qualifier("loanInfoQueryService")
    LoanInfoQueryService loanInfoQueryService;

	@Autowired
	@Qualifier("accLoanService")
    AccLoanService accLoanService;

	@Autowired
	@Qualifier("accLoanRepayPlanService")
    LoanRepayPlanService loanRepayPlanService;

	@Autowired
	@Qualifier("pubSysInfoService")
	private PubSysInfoService pubSysInfoService;

}
